package mq

import (
	"emicro_test/emicro_8/grpc_server/mail/common"
	"emicro_test/emicro_8/grpc_server/mail/utils"
	"encoding/json"
	"fmt"
	RabbimqPool "gitee.com/tym_hmm/rabbitmq-pool-go"
	"github.com/BurntSushi/toml"
	"log"
)

var SubMqPool *RabbimqPool.RabbitPool

type Consumer struct{
	ExchangeName string
	ExchangeType string
	Route string
	QueueName string
	IsTry bool
	IsAutoAck bool
	MaxReTry int
}

type config struct {
	Consumers map[string]Consumer `toml:"Rabbitmq"`
}

func InitRabbitmq() {
	SubMqPool = RabbimqPool.NewConsumePool()
	SubMqPool.SetMaxConnection(10)
	SubMqPool.SetMaxConsumeChannel(10)
	rabAddr := common.Config.String("rabmq_addr")
	rabPort, _ := common.Config.Int("rabmq_port")
	rabUser := common.Config.String("rabmq_user")
	rabPwd := common.Config.String("rabmq_pwd")
	err:= SubMqPool.ConnectVirtualHost(rabAddr, rabPort, rabUser, rabPwd, "/")
	if err != nil {
		log.Println("InitRabbitmq Err:", err)
	}
	InitConsumer()
}

func InitConsumer() {
	var conf config
	_, err := toml.DecodeFile("./lib/conf/mq.toml", &conf)
	if err !=nil {
		log.Println("parse mq.toml Err:", err)
		return
	}
	for _, q := range conf.Consumers{
		consumeReceive := &RabbimqPool.ConsumeReceive{
			ExchangeName: q.ExchangeName,
			ExchangeType: q.ExchangeType,
			Route:        q.Route,
			QueueName:    q.QueueName,
			IsTry:        q.IsTry,  				//是否重试
			IsAutoAck:    q.IsAutoAck, 				//自动消息确认
			MaxReTry:     int32(q.MaxReTry),     	//最大重试次数
			EventFail: func(code int, e error, data []byte) {
				log.Printf("error:%s", e)
			},
			EventSuccess: successHandler(q),
		}
		SubMqPool.RegisterConsumeReceive(consumeReceive)
	}

	go func() {
		err := SubMqPool.RunConsume()
		if err != nil {
			log.Println("InitConsumer Err:", err)
		}
	}()
}

func successHandler(consumer Consumer) func(data []byte, header map[string]interface{}, retryClient RabbimqPool.RetryClientInterface) bool{
	switch consumer.QueueName {
	case "user_reg":
		return user_reg_handler()
	}
	return nil
}

func user_reg_handler() func(data []byte, header map[string]interface{}, retryClient RabbimqPool.RetryClientInterface) bool {
	return func(data []byte, header map[string]interface{}, retryClient RabbimqPool.RetryClientInterface) bool { //如果返回true 则无需重试
		log.Printf("user_reg_handler data:%s\n", string(data))

		//解析json数据
		var user struct{
			Id int32
			Name string
			Phone string
			Email string
		}
		err := json.Unmarshal(data, &user)
		if err != nil{
			log.Println("user_reg_handler Unmarshal Err:", err)
			return false
		}

		//推送邮件
		Body := fmt.Sprintf("Hello. The name is %v and the phone is %v register success!!", user.Name, user.Phone)
		err = utils.SendMail(user.Email, Body)
		if err != nil{
			log.Println("user_reg_handler Err:", err)
			return false
		}

		retryClient.Ack()
		return true
	}
}

